<template>
  <main-card
    ref="myComponentRef"
    :crumbs="crumbs"
    :show-content-padding="false"
    :loading="loading"
    :screen-style-obj="computedScreenStyleObj"
    is-fixed-body
    title="标注详情"
  >
    <template #title>
      <div class="page-title">
        <div class="mr-12 default-title elliptical-1" :title="taskInfo.name">{{ taskInfo.name }}</div>
        <div :class="['task-type', taskType === 'img' ? 'red' : 'blue']">{{ pageOption.title }}</div>
      </div>
    </template>
    <template #tool-btn>
      <a-dropdown placement="bottom">
        <a-button class="icon-only-btn" @click.stop>
          <i class="iconfont icon-more-line" style="font-size: 18px"></i>
        </a-button>
        <template #overlay>
          <a-menu>
            <a-menu-item @click="goMarkEdit"> 编辑 </a-menu-item>
            <a-menu-item @click="openDeleteTaskModal"> 删除 </a-menu-item>
          </a-menu>
        </template>
      </a-dropdown>
    </template>
    <template #screen-space>
      <div>
        {{ taskInfo.description }}
      </div>
    </template>
    <div class="mt-24 task-detail">
      <div class="task-detail__info">
        <div class="elliptical-1 max-w-800" :title="taskInfo.name">{{ taskInfo.name }}</div>
        <div class="mx-24">
          <svg xmlns="http://www.w3.org/2000/svg" width="2" height="20" viewBox="0 0 2 20" fill="none">
            <path d="M1 0V20" stroke="#D9D9DB" />
          </svg>
        </div>

        <div class="mr-12 sub-text">创建时间</div>
        <div class="mr-12">{{ taskInfo.createTime }}</div>
        <div class="flex-1"></div>
        <div class="mr-12 sub-text">完成度</div>
        <div class="h-25">
          <a-progress class="w-180" :percent="taskProgressData.progress || 0" />
        </div>
      </div>
      <!-- 图片内容 -->
      <div ref="leftRef" class="detail__left">
        <div class="pt-20 fbc h-50">
          <div class="tab-box">
            <div :class="['tab', activeTab == -1 && 'tab--active']" @click="changeListMarkType(-1)">
              全部（{{ taskProgressData.totalCount }}）
            </div>
            <div :class="['tab', activeTab == 1 && 'tab--active']" @click="changeListMarkType(1)">
              已标注（{{ taskProgressData.hasMarkCount }}）
            </div>
            <div :class="['tab', activeTab == 0 && 'tab--active']" @click="changeListMarkType(0)">
              未标注（{{ taskProgressData.noMarkCount }}）
            </div>
          </div>
          <div v-if="taskInfo.markRecordVO" class="mr-12 mt-[-8px]">
            上次标注：
            <a-button type="link" :title="taskInfo.markRecordVO.fileName" @click="goMark(taskInfo.markRecordVO)">
              {{ lineClamp(taskInfo.markRecordVO.fileName, 30) }}
            </a-button>
          </div>
        </div>

        <div v-if="dataList?.length > 0" class="img-box my-scrollbar">
          <div
            v-for="(item, index) in dataList"
            :key="item.id"
            :class="['img-li', `img-li--num${listLimit}`]"
            @mouseover="hoverIndex = index"
            @mouseleave="hoverIndex = undefined"
            @click="goMark(item)"
          >
            <!-- <img :src="item.fileUrl" /> -->
            <img :src="customImgUrl(item.pathUrl, 360, 187)" />
            <template v-if="item.markType === 1">
              <img src="@/assets/img/dmp/marked.svg" class="no-mark-icon" />
              <div class="mask"></div>
            </template>
            <div class="maker">
              <div class="img-text" :title="item.fileName">{{ item.fileName }}</div>
              <div class="full-screen-btn" @click.stop="previewImg(item)">
                <i class="iconfont icon-fullscreen-line"></i>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="img-box my-scrollbar empty-box">
          <!-- <a-empty /> -->
          <default-graph title="暂无数据">
            <img src="@/assets/img/no-course.svg" alt="加载失败" />
          </default-graph>
        </div>
        <div v-if="dataList?.length > 0" class="pagination">
          <g-pagination
            v-model:offset="listOffset"
            v-model:limit="listLimit"
            :total="listTotal"
            :page-size-options="['12', '24', '40', '72']"
            @change="getListData"
          />
        </div>
      </div>
      <!-- 标签 图片分类-->
      <div v-if="taskType === 'img'" class="detail__right img-tag">
        <div class="tag-tab">
          <div v-show="!tagIsSearch" class="no-search">
            <div class="name">标签</div>
            <div>
              <span class="search-icon" @click="showTagIsSearch(true)"><i class="iconfont icon-search-line"></i></span>
              <span class="add-btn" @click="addTag"><i class="iconfont icon-add-line"></i></span>
            </div>
          </div>
          <div v-show="tagIsSearch" class="search">
            <a-input
              ref="imgInputRef"
              v-model:value="tagSearchValue"
              placeholder="请输入标签"
              allow-clear
              @keyup.enter="getTaskTag()"
              @blur="showTagIsSearch(false)"
            >
              <template #prefix>
                <i class="iconfont icon-search-line"></i>
              </template>
              <!-- <template #suffix>
                <div @click=";(tagSearchValue = ''), (tagIsSearch = false), getTaskTag()" class="close-search-btn">
                  <close-circle-filled />
                </div>
              </template> -->
            </a-input>
          </div>
        </div>
        <div class="tag-column">
          <div>名称</div>
          <a-tooltip placement="top">
            <template #title>
              {{ tagSortValue === 0 ? '点击升序' : tagSortValue === 1 ? '点击降序' : '取消排序' }}
            </template>
            <div class="number" @click="tagSort">
              <div class="sort-btn">
                <div :class="['btn', tagSortValue === 1 && 'btn--active']"><caret-up-outlined /></div>
                <div :class="['btn', tagSortValue === 2 && 'btn--active']"><caret-down-outlined /></div>
              </div>
              <div>数量</div>
            </div>
          </a-tooltip>
        </div>
        <div class="tag-list my-scrollbar">
          <div
            v-for="(item, index) in tagList"
            :key="item.id"
            :class="['tag-li', editTagIndex == index && 'tag-li--active']"
            @mouseover="hoverTagIndex = index"
            @mouseleave="hoverTagIndex = undefined"
          >
            <div class="tag-name">
              <a-tooltip v-if="editTagIndex !== index">
                <template #title> {{ item.name }}</template>
                <span>{{ item.name }} </span>
              </a-tooltip>
              <a-input v-else v-model:value="editTagValue" v-trim :maxlength="20" @keyup.enter="confirmEditTag(item, index)" />
            </div>
            <div v-if="hoverTagIndex != index && editTagIndex !== index">{{ item.number }}</div>
            <div v-else-if="hoverTagIndex == index && editTagIndex !== index" class="hover-btn">
              <span class="btn" @click="editTag(item, index)"><i class="iconfont icon-edit-line"></i></span>
              <span class="btn" @click="deleteTag(item)"><i class="iconfont icon-delete-bin-6-line"></i></span>
            </div>
            <div v-else class="edit-btn">
              <span class="btn" @click="confirmEditTag(item, index)"><i class="iconfont icon-check-line"></i></span>
              <span class="btn" @click="cancelEditTag(item)"><i class="iconfont icon-close-line"></i></span>
            </div>
          </div>
        </div>
      </div>
      <!-- 标签 目标检测 -->
      <div v-else-if="taskType === 'obj'" class="detail__right obj-tag">
        <div class="tag-tab">
          <div v-if="!tagIsSearch" class="no-search">
            <div class="name">标签</div>
            <div>
              <span class="search-icon" @click="showTagIsSearchObj(true)"><i class="iconfont icon-search-line"></i></span>
              <span class="add-btn" @click="handleOpenTagForm()"><i class="iconfont icon-add-line"></i></span>
            </div>
          </div>
          <div v-else class="search">
            <a-input
              ref="objInputRef"
              v-model:value="tagSearchValue"
              v-trim
              placeholder="请输入标签"
              allow-clear
              @keyup.enter="getTaskTag()"
              @blur="showTagIsSearchObj(false)"
            >
              <template #prefix>
                <i class="iconfont icon-search-line cursor-pointer"></i>
              </template>
              <!-- <template #suffix>
                <div @click=";(tagSearchValue = ''), (tagIsSearch = false), getTaskTag()" class="close-search-btn">
                  <close-circle-filled />
                </div>
              </template> -->
            </a-input>
          </div>
        </div>
        <div class="tag-column">
          <div class="name">名称</div>
          <div class="attribute">属性</div>
          <a-tooltip placement="top">
            <template #title>
              {{ tagSortValue === 0 ? '点击升序' : tagSortValue === 1 ? '点击降序' : '取消排序' }}
            </template>
            <div class="number" @click="tagSort">
              <div class="sort-btn">
                <div :class="['btn', tagSortValue === 1 && 'btn--active']"><caret-up-outlined /></div>
                <div :class="['btn', tagSortValue === 2 && 'btn--active']"><caret-down-outlined /></div>
              </div>
              <div>数量</div>
            </div>
          </a-tooltip>
        </div>
        <div class="tag-list my-scrollbar">
          <div
            v-for="(item, index) in tagList"
            :key="item.id"
            class="tag-li"
            @mouseover="hoverTagIndex = index"
            @mouseleave="hoverTagIndex = undefined"
          >
            <div class="tag-name">
              <a-tooltip>
                <template #title> {{ item.name }}</template>
                <span :style="{ backgroundColor: hexToRgba(item.color as string, 0.08).rgba as string, color: item.color}">
                  {{ item.name }}
                </span>
              </a-tooltip>
            </div>
            <div v-if="hoverTagIndex != index" class="content">
              {{ item.attributeList?.map(item => item.name).toString() }}
            </div>
            <div v-if="hoverTagIndex != index" class="number">
              {{ item.number }}
            </div>
            <div v-if="hoverTagIndex == index" class="hover-btn">
              <span class="btn" @click.stop="handleEdit(item)"><i class="iconfont icon-equalizer-line"></i></span>
              <span class="btn" @click="deleteTag(item)"><i class="iconfont icon-delete-bin-6-line"></i></span>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 图片预览 图像分类 -->
    <template v-if="taskType === 'img'">
      <a-modal
        v-model:open="previewVisible"
        centered
        :closable="!loading"
        :keyboard="false"
        :mask-closable="false"
        width="1000px"
        :footer="null"
        ok-type="default"
        cancel-text=""
        destroy-on-close
        :body-style="{ height: '780px', padding: '12px !important' }"
        @cancel="previewData = null"
      >
        <template #title>
          <div class="ant-modal-title" :title="previewData ? previewData.fileName : ''">{{ previewData ? previewData.fileName : '' }}</div>
        </template>
        <div class="file-content-img">
          <div class="result-are">
            <a-spin :spinning="loading" tip="加载中">
              <canvas id="canvas" ref="canvasRef" width="726" height="732"></canvas>
            </a-spin>
          </div>
          <div class="mark-result">
            <div class="result-title">标注结果</div>
            <div class="result-list my-scrollbar">
              <div v-for="(item, index) in markData" :key="index" class="result-li">
                <div class="result-li-left">
                  <span class="tag-text" :title="item.name">{{ item.name }}</span>
                </div>
              </div>
            </div>
            <div class="goto-mark">
              <a-button class="btn" @click="goMark(previewData!)">标注</a-button>
            </div>
          </div>
        </div>
      </a-modal>
    </template>
    <!-- 图片预览 目标检测 -->
    <template v-else-if="taskType === 'obj'">
      <a-modal
        v-model:open="previewVisible"
        centered
        :closable="!loading"
        :keyboard="false"
        :mask-closable="false"
        width="1020px"
        :footer="null"
        ok-type="default"
        cancel-text=""
        :body-style="{ height: '780px', padding: '12px !important' }"
        @cancel="previewData = null"
      >
        <template #title>
          <div class="ant-modal-title" :title="previewData ? previewData.fileName : ''">{{ previewData ? previewData.fileName : '' }}</div>
        </template>
        <div class="file-content-img">
          <div class="result-are">
            <a-spin :spinning="loading" tip="加载中">
              <canvas id="canvas" ref="canvasRef" width="726" height="732"></canvas>
            </a-spin>
          </div>
          <div class="mark-result">
            <div class="result-title">标注结果</div>
            <div class="result-list my-scrollbar">
              <div
                v-for="(item, index) in markData"
                :key="index"
                class="result-li"
                :style="{
                color: markDataShow ? item.markTagInfo.color : '#ceced4',
                background: markDataShow ?  resultHoverIndex === index ?   hexToRgba(item.markTagInfo.color as string, 0.3).rgba : hexToRgba(item.markTagInfo.color as string, 0.08).rgba :  '#fbfbfc',
                border: markDataShow ? index === selectedObjectIndex ?  `3px solid ${item.markTagInfo.color}` : resultHoverIndex === index ? `1px solid ${item.markTagInfo.color}`:  '1px solid rgba(0, 0, 0, 0.05)':  '1px solid rgba(0, 0, 0, 0.05)',}"
              >
                <div class="result-li-left">
                  <i :class="['iconfont', filterArrayByValue(item.type as string, toolsBtn)?.iconClass]"></i>
                  <span class="tag-text" :title="item.markTagInfo.name">{{ item.markTagInfo.name }}</span>
                </div>
              </div>
            </div>
            <div class="goto-mark">
              <a-button class="btn" @click="goMark(previewData!)">标注</a-button>
            </div>
          </div>
        </div>
      </a-modal>
    </template>

    <!-- 标签表单 -->
    <tag-form v-if="taskType === 'obj'" ref="tagFormRef" :title="tagFormTitle" @onSubmit="confirmAddEditTag" />
  </main-card>
  <delete-confirm-dialog v-model:show="isDeleteDialogShow" :confirm-name="taskInfo?.name" @ok="onDeleteTask" />
</template>

<script lang="ts" setup>
  import { message, Modal } from 'ant-design-vue'
  import { fabric } from 'fabric'
  import { hexToRgba } from 'g6-fn'
  import { computed, createVNode, nextTick, onMounted, Ref, ref } from 'vue'
  import { useRequest } from 'vue-request'
  import { useRoute, useRouter } from 'vue-router'

  import DeleteConfirmDialog from '@/components/DeleteConfirmDialog/index.vue'
  import WarnIcon from '@/components/icon/IconWarn/index.vue'
  import MainCard from '@/components/MainCard/index.vue'
  import { dmpTaskApi } from '@/services/api'
  import { customImgUrl, regex } from '@/utils'
  import { filterArrayByValue, lineClamp } from '@/utils'

  import TagForm from '../components/TagForm.vue'
  import { MarkObj, TaskDataLi, TaskInfo, TaskTag } from '../types'
  import { drawMarkInCanvas, markPositionInCanvas } from '../utils'

  const router = useRouter()
  const route = useRoute()

  const taskId = ref(route.params.id as string)
  const taskType = ref(route.params.type as 'img' | 'obj')

  // 根据type判断页面信息
  const pageOption = {
    img: {
      title: '图像分类',
      editTaskRouteName: 'mark-img',
      color: 'red'
    },
    obj: {
      title: '目标检测',
      editTaskRouteName: 'mark-obj',
      color: 'blue'
    }
  }[taskType.value]

  const crumbs = ref([{ name: '数据标注', path: '/dmp/task-list' }, { name: '' }])

  const mainDataHeight = ref()
  const loading = computed(
    () => isImgLoading.value || isGetImgListLoading.value || isGetTaskDetailLoading.value || isDeleteTaskLoading.value
  )
  //修改main-card样式
  const computedScreenStyleObj = computed(() => {
    return {
      paddingBottom: '8'
    }
  })
  /* 任务查询、删除、修改、标注------------------------------------------------------------------------------------------------- */
  // 详情
  const {
    data: taskDetailData,
    runAsync: runGetTaskDetail,
    loading: isGetTaskDetailLoading
  } = useRequest<{ data: TaskInfo }>(dmpTaskApi.detail)
  const getTaskDetail = async (id: string) => {
    await runGetTaskDetail(id)
    Object.assign(taskInfo.value, taskDetailData.value?.data || {})
    crumbs.value[1].name = taskInfo.value.name
  }
  //删除
  const { runAsync: runDeleteTask, loading: isDeleteTaskLoading } = useRequest<ResponseData<any>>(dmpTaskApi.del)

  const isDeleteDialogShow = ref(false)
  const openDeleteTaskModal = () => {
    isDeleteDialogShow.value = true
  }
  const onDeleteTask = async () => {
    await runDeleteTask({}, { urlParams: { id: taskInfo.value.id } })
    message.success('删除成功')
    router.push('/dmp/task-list')
  }
  //标注
  const goMark = (item: TaskDataLi) => {
    window.open(`/dmp/${pageOption.editTaskRouteName}/${taskId.value}?id=${item.id}`)
  }
  // 修改
  const goMarkEdit = () => {
    router.push({
      path: `/dmp/edit/${taskId.value}`
    })
  }
  /* ------------------------------------------------------------------------------------------------- */

  // 图片缩放比例
  const imgScale = ref<number>()

  const canvasRef = ref()
  const tagFormRef = ref()
  let canvas: fabric.Canvas
  let myImage: fabric.Image
  const isImgLoading = ref(false) //标注图片加载的loading
  let markData = ref<MarkObj[] | null>([]) // 标注数据
  const markDataShow = ref(true)
  const resultHoverIndex = ref()
  let selectedObjectIndex = ref<number | null>() // 选中的对象的索引
  const toolsBtn = ref([
    { name: '矩形', value: 'rect', iconClass: 'icon-Square-line' },
    { name: '圆', value: 'circle', iconClass: 'icon-circle-line' },
    { name: '多边形', value: 'polygon', iconClass: 'icon-Multilateral-line' },
    { name: '实线', value: 'line', iconClass: 'icon-line-line' },
    { name: '虚线', value: 'dottedLine', iconClass: 'icon-Dottedline-line' },
    { name: '点', value: 'point', iconClass: 'icon-point-line' }
  ])

  // 维护一个对象数组，用于记录画布状态
  const initCanvas = async (imgUrl: string) => {
    canvas = new fabric.Canvas(canvasRef.value) // 创建画布
    canvas.selection = false // 禁止选中
    await loadImage(imgUrl)
  }

  // TODO: 标注图片
  const loadImage = (url: any) => {
    return new Promise(rs => {
      fabric.Image.fromURL(url, (i: any) => {
        i.hasControls = false // 禁止控制角
        imgScale.value = Math.min((canvas.getWidth() - 4) / i.width, (canvas.getHeight() - 4) / i.height)
        i.scale(imgScale.value)

        myImage = i
        myImage.set({
          selectable: false,
          evented: false,
          type: 'image'
        })

        // 将图片添加到画布
        canvas.add(myImage)
        // 使图片居中
        canvas.centerObject(myImage)
        canvas.setBackgroundImage(myImage, canvas.renderAll.bind(canvas))
        canvas.setViewportTransform([1, 0, 0, 1, 0, 0])
        // 刷新画布
        canvas.renderAll()
        rs(true)
      })
    })
  }

  // 标签数据
  const tagSearchValue = ref()
  const tagSortValue = ref<number>(0)
  const editTagIndex = ref<undefined | number>()
  const hoverTagIndex = ref()
  const tagIsSearch = ref(false)
  const editTagValue = ref<string>()
  const tagFormTitle = ref('新增标签')

  // 数据
  const previewData = ref<TaskDataLi | null>() // 预览文件内容
  const activeTab = ref(-1)
  const previewVisible = ref(false)
  const hoverIndex = ref<number>()

  // 进度条
  const taskProgressData = ref({
    progress: 0,
    totalCount: 0,
    noMarkCount: 0,
    hasMarkCount: 0
  })

  const dataList = ref<TaskDataLi[]>([])
  const tagList = ref<TaskTag[]>([])
  const tagColumns = ref()

  const taskInfo = ref<TaskInfo>({
    name: '',
    taskBucketList: [],
    progress: '',
    description: '',
    createTime: ''
  })

  // TODO:获取页面数据
  const listOffset = ref(1)
  const listLimit = ref(12)
  const listTotal = ref(0)

  // 获取标注信息
  const {
    data: getBucketDataRes,
    runAsync: runGetBucketData,
    loading: isGetImgListLoading
  } = useRequest<ResponseData>(dmpTaskApi.taskBucketData)
  const getListData = async () => {
    let params = {
      taskId: taskId.value,
      markType: activeTab.value,
      offset: listOffset.value,
      limit: listLimit.value
    }

    await runGetBucketData(params)
    const data = getBucketDataRes.value?.data
    dataList.value = data.records
    listTotal.value = data.total
  }

  // 切换数据类型
  const changeListMarkType = (type: number) => {
    activeTab.value = type
    listOffset.value = 1
    getListData()
    taskProgress()
  }

  // 根据类型打开标签表单
  const handleOpenTagForm = () => {
    tagFormTitle.value = '新增标签'
    tagFormRef.value.open()
  }
  // 物体标注表单编辑
  const handleEdit = (row: any) => {
    tagFormTitle.value = '编辑标签'
    tagFormRef.value.setForm(row)
    tagFormRef.value.open()
  }

  // 获取任务进度
  const taskProgress = async () => {
    let { data } = await dmpTaskApi.taskProgress(taskId.value)
    if (data) {
      taskProgressData.value = data
    }
  }

  // 获取标注信息
  const getMarkInfo = async (id: string | number) => {
    let { data } = await dmpTaskApi.taskDataMarkInfo(id)
    if (!data.markInfoList) {
      return
    }
    if (taskType.value === 'img') {
      markData.value = data.markInfoList
      return
    }

    await renderMarkInfo(data.markInfoList)
  }

  // 渲染目标检测标注信息
  const renderMarkInfo = (markInfoList: any[]) => {
    return new Promise(rs => {
      markInfoList.forEach((item: any) => {
        const markTagInfo: { [x: string]: any } = {}
        markTagInfo.attributeList = item.childList?.map((i: any) => {
          return {
            id: i.taskTagAttributeId,
            name: i.name,
            value: i.value
          }
        })
        markTagInfo.id = item.taskTagId
        markTagInfo.name = item.name
        markTagInfo.color = item.color
        let pointsOfImg = JSON.parse(item.points)

        let pointsOfCanvas = markPositionInCanvas(myImage, pointsOfImg, imgScale.value, item.type)

        let drawObject = drawMarkInCanvas(markTagInfo, item.type, pointsOfCanvas)
        if (drawObject === null) {
          return
        }
        canvas.add(drawObject!)
        // TODO: 添加标注信息到画布
        // 获取矩形中心点坐标
        const centerPoint = drawObject.getCenterPoint()
        // 创建 IText 对象
        const text = new fabric.IText(drawObject.markTagInfo.name, {
          fontSize: 14,
          fill: drawObject!.markTagInfo.color,
          textAlign: 'center',
          type: 'text',
          selectable: false
        })
        text.set({
          left: centerPoint.x - text.width! / 2,
          top: centerPoint.y - text.height! / 2
        })
        drawObject.on('moving', function () {
          const centerPoint = drawObject.getCenterPoint()
          text.set({
            left: centerPoint.x,
            top: centerPoint.y
          })
        })
        drawObject.on('modified', function () {
          const centerPoint = drawObject.getCenterPoint()
          text.set({
            left: centerPoint.x,
            top: centerPoint.y
          })
        })
        drawObject.on('removed', function () {
          canvas.remove(text)
        })

        // 将 IText 对象添加到画布中
        canvas.add(text)

        drawObject.set({
          fill: item.type !== 'point' ? hexToRgba(item.color, 0.08).rgba : item.color,
          stroke: item.color,
          selectable: false
        })
        markData.value?.push(drawObject)
      })
      // 在canvas渲染好后关闭loading
      fabric.util.requestAnimFrame(() => {
        console.warn('标注渲染完成')
        rs(true)
      })
    })
  }

  //   预览图片
  const previewImg = (item: TaskDataLi) => {
    previewVisible.value = true
    previewData.value = item
    markData.value = []
    nextTick(async () => {
      isImgLoading.value = true
      await initCanvas(item.fileUrl)
      await getMarkInfo(item.id)
      isImgLoading.value = false
    })
  }

  /* 标签 ----------------------------------------------------------------------------------------------- */
  // 标签状态栏变为搜索
  const getTaskTag = async () => {
    let params = {
      columns: tagColumns.value,
      order: tagSortValue.value === 2 ? 'desc' : tagSortValue.value === 1 ? 'asc' : '',
      taskId: taskId.value,
      name: tagSearchValue.value
    }
    let { data } = await dmpTaskApi.taskTag(params)
    tagList.value = data
  }
  //img标签状态
  const imgInputRef: Ref<HTMLInputElement | null> = ref(null)

  const showTagIsSearch = (type: boolean): void => {
    tagIsSearch.value = type
    if (type) {
      nextTick(() => imgInputRef.value?.focus())
    }
  }

  //obj标签状态
  const objInputRef: Ref<HTMLInputElement | null> = ref(null)

  const showTagIsSearchObj = (type: boolean): void => {
    tagIsSearch.value = type
    if (type) {
      nextTick(() => objInputRef.value?.focus())
    }
  }

  //  标签排序
  const tagSort = () => {
    let newValues = tagSortValue.value === 2 ? 0 : tagSortValue.value + 1
    tagSortValue.value = newValues
    getTaskTag()
  }

  // 点击开始编辑标签
  const editTag = (item: any, index: any) => {
    console.log(item, index, editTagIndex.value + '')
    if (editTagIndex.value + '' !== 'undefined') {
      message.error('请先完成当前正在编辑的标签')
      return
    }
    editTagIndex.value = index
    editTagValue.value = item.name
  }

  // 确定编辑标签内容
  const confirmEditTag = async (item: any, index: any) => {
    if (!editTagValue.value) {
      message.error('标签名称不能为空')
      return
    }
    if (!regex.basicName.test(editTagValue.value)) {
      message.error('仅支持中英文、数字、横线、下划线、括号、小数点')
      return
    }
    let paramsAdd = {
      name: editTagValue.value,
      taskId: taskInfo.value.id,
      attributeList: [],
      color: ''
    }
    let paramsEdit = {
      id: item.id,
      name: editTagValue.value,
      attributeList: [],
      color: ''
    }
    item.addEdit
      ? await dmpTaskApi.taskTagAdd(paramsAdd, {
          isAddUid: true
        })
      : await dmpTaskApi.taskTagEdit(paramsEdit, {
          isAddUid: true
        })
    if (item.addEdit === true) {
      tagList.value[index].addEdit = false
    }
    tagList.value[index].name = editTagValue.value
    editTagIndex.value = undefined
    editTagValue.value = undefined
    getTaskTag()
  }

  //   取消编辑标签
  const cancelEditTag = (item: TaskTag) => {
    if (item.addEdit === true) {
      tagList.value.splice(0, 1)
      editTagValue.value = ''
      editTagIndex.value = undefined
    } else {
      editTagValue.value = ''
      editTagIndex.value = undefined
    }
  }

  //   删除标签
  const deleteTag = (item: TaskTag) => {
    if (taskType.value === 'img') {
      if (editTagIndex.value + '' !== 'undefined') {
        message.error('请先完成当前正在编辑的标签')
        return
      }
    }
    Modal.confirm({
      title: '确定删除?',
      icon: createVNode(WarnIcon),
      content: '删除后，标签不可恢复',
      okText: '确定',
      cancelText: '取消',
      centered: true,
      onOk: async () => {
        await dmpTaskApi.taskTagDel({}, { urlParams: { id: item.id } })
        await getListData()
        await getTaskTag()
        await taskProgress()
      }
    })
  }

  const confirmAddEditTag = async (data: any) => {
    const newData = { ...data, taskId: taskId.value }
    newData.attributeList = newData.attributeList.filter((item: any) => item?.name?.trim() !== '')
    if (newData.id) {
      await dmpTaskApi.taskTagEdit(newData, {
        isAddUid: true
      })
    } else {
      await dmpTaskApi.taskTagAdd(newData, {
        isAddUid: true
      })

      // TODO: 模拟新增
      tagList.value.push(newData)
    }
    tagFormRef.value.close()
    tagFormRef.value.resetForm()
    getTaskTag()
  }

  // 新增标签
  const addTag = () => {
    if (editTagIndex.value + '' !== 'undefined') {
      message.error('请先完成当前正在编辑的标签')
      return
    }
    let addTag: TaskTag = { name: '', id: '0', addEdit: true }
    tagList.value.splice(0, 0, addTag)
    editTagIndex.value = 0
  }

  onMounted(async () => {
    mainDataHeight.value = document.getElementById('mainData')?.offsetHeight
    await getListData()
    await getTaskDetail(taskId.value)
    await getTaskTag()
    await taskProgress()
  })
</script>

<style lang="less" scoped>
  @import '@/styles/mixins.less';

  :deep(.pagination--my) {
    border: none;
  }

  :deep(.ant-pagination) {
    padding-left: 0 !important;
  }

  .page-title {
    display: flex;
    align-items: center;

    .default-title {
      .font20b();

      max-width: 1000px;
    }

    .task-type {
      display: inline-block;
      padding: 3px 6px;
      border-radius: 6px;
      line-height: 22px;

      &.blue {
        color: #4154d1;
        background: rgba(65, 84, 209, 0.08);
        border: 1px solid rgba(0, 0, 0, 0.05);
      }

      &.red {
        color: #d61860;
        background: rgba(214, 24, 96, 0.08);
        border: 1px solid rgba(0, 0, 0, 0.05);
      }
    }
  }

  .task-detail {
    position: relative;
    display: flex;
    justify-content: space-between;
    overflow: hidden;
    padding-bottom: 20px;
    height: 668px;
    background-color: #fff;
    border: 1px solid @border1;
    border-radius: 10px;
    flex-wrap: wrap;

    .task-detail__info {
      display: flex;
      align-items: center;
      padding: 10px 24px;
      width: 100%;
      height: 56px;
      color: @text01;
      border-bottom: 1px solid rgba(0, 0, 0, 0.05);

      .sub-text {
        color: @text03;
      }
    }

    .detail__left {
      width: calc(100% - 280px);
      height: calc(100% - 56px);

      .tab-box {
        display: flex;
        padding: 0 24px;
        height: 100%;

        .tab {
          padding-bottom: 9px;
          margin: 0 20px;
          cursor: pointer;
          min-width: 100px;
          font-size: 16px;
          text-align: center;
          color: rgba(25, 25, 48, 0.75);
          font-weight: 500;

          &:first-child {
            margin-left: 0;
          }

          &--active {
            position: relative;
            color: rgba(16, 16, 20, 0.95);
            font-weight: 700;

            &::after {
              position: absolute;
              bottom: 0;
              left: 0;
              display: block;
              width: 100%;
              height: 3px;
              background: #1868e9;
              content: '';
            }
          }
        }
      }

      .img-box {
        display: flex;
        overflow-y: auto;
        padding: 8px 16px 8px 24px;
        height: calc(100% - 50px - 48px); //高度需减去tab、分页器、外边距高度
        max-height: calc(100% - 50px - 48px);
        flex-wrap: wrap;
        align-content: flex-start;

        &.empty-box {
          display: flex;
          justify-content: center;
          align-items: center;
          width: 100%;
          height: calc(100% - 48px);
        }

        .img-li {
          position: relative;
          margin-right: 8px;
          margin-bottom: 8px;
          width: 240px;
          height: 142px;
          border-radius: 2px;

          &--num12 {
            width: 254px;
            height: 154px;
          }

          &--num24 {
            width: 235px;
            height: 135px;
          }

          &--num40 {
            width: 172px;
            height: 103px;
          }

          &--num72 {
            width: 110px;
            height: 90px;
          }

          .no-mark-icon {
            position: absolute;
            top: 4px;
            left: 4px;
            z-index: 3;
            width: 20px;
            height: 20px;
          }

          .mask {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 2;
            width: 100%;
            height: 100%;
            background-color: rgba(25, 25, 48, 0.2);
          }

          img {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }

          .maker {
            position: absolute;
            bottom: 0;
            z-index: 10;
            display: flex;
            justify-content: space-between;
            width: 100%;
            height: 24px;
            font-size: 12px;
            color: #fff;
            background: rgba(25, 25, 48, 0.45);
            border-radius: 0 0 2px 2px;
            line-height: 24px;
            box-sizing: border-box;

            .full-screen-btn {
              // padding: 0 6px;
              width: 20%;
              text-align: center;
              border-left: 1px solid rgba(255, 255, 255, 0.5);
              cursor: pointer;
            }

            .img-text {
              padding-left: 4px;
              width: 80%;
              .elliptical-1();
            }
          }
        }
      }

      .pagination {
        padding: 8px 24px 0;

        .pagination--my {
          margin-top: 0;
        }
      }
    }

    .detail__right.img-tag {
      display: flex;
      width: 280px;
      height: calc(100% - 56px);
      background: white;
      flex-direction: column;
      border-left: 1px solid #d9d9db;

      .tag-tab {
        height: 66px;

        .no-search {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 20px 20px 20px 24px;

          .name {
            color: rgba(25, 25, 48, 0.75);
            .font14b();
          }

          .add-btn {
            display: inline-block;
            margin-left: 17px;
            width: 26px;
            height: 26px;
            font-size: 16px;
            text-align: center;
            color: rgba(25, 25, 48, 0.75);
            border-radius: 6px;
            line-height: 26px;
            cursor: pointer;

            &:hover {
              background: rgba(0, 0, 0, 0.05);
            }
          }

          .search-icon {
            display: inline-block;
            width: 26px;
            height: 26px;
            font-size: 16px;
            text-align: center;
            color: rgba(25, 25, 48, 0.75);
            cursor: pointer;
            line-height: 26px;
            border-radius: 6px;

            &:hover {
              background: rgba(0, 0, 0, 0.05);
            }
          }
        }

        .search {
          padding: 12px 24px;

          .close-search-btn {
            cursor: pointer;
            color: rgba(25, 25, 48, 0.75);
          }
        }
      }

      .tag-column {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 11px 24px;
        height: 40px;
        border-bottom: 1px solid #e8e8eb;

        .name {
          padding-left: 8px;
          width: 92px;
        }

        .attribute {
          display: flex;
          align-items: center;
          padding-left: 8px;
          width: calc(100% - 150px);
        }

        .number {
          cursor: pointer;
          display: flex;
          align-items: center;

          .sort-btn {
            margin-right: 10px;

            .btn {
              width: 9px;
              font-size: 10px;
              color: rgba(25, 25, 48, 0.2);

              &:first-child {
                margin-top: 1px;
              }

              &:last-child {
                margin-top: -3px;
              }

              &--active {
                color: @primary1;
              }
            }
          }
        }
      }

      .tag-list {
        flex: 1;
        overflow-y: auto;
        padding: 8px 0;
        margin-top: 8px;

        .tag-li {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 11px 24px;
          margin-bottom: 8px;
          height: 44px;

          &:hover {
            background: #f5f5f5;
          }

          &--active {
            background: #f5f5f5;
          }

          .tag-name {
            width: calc(100% - 68px);
            .elliptical-1();
          }

          .hover-btn {
            .btn {
              display: inline-block;
              width: 26px;
              height: 26px;
              font-size: 14px;
              text-align: center;
              color: rgba(16, 16, 20, 0.95);
              border-radius: 6px;
              cursor: pointer;
              line-height: 26px;

              &:hover {
                background: rgba(0, 0, 0, 0.05);
              }

              &:last-child {
                margin-left: 16px;
              }
            }
          }

          .edit-btn {
            display: flex;

            .btn {
              cursor: pointer;
              display: inline-block;
              width: 24px;
              height: 24px;
              text-align: center;
              border: 1px solid #d9d9db;
              border-radius: 6px;
              line-height: 24px;

              &:first-child {
                margin-right: 8px;
                color: #fff;
                background: #d61860;
                border: 1px solid #d61860;
              }
            }
          }
        }
      }
    }

    .detail__right.obj-tag {
      z-index: 999;
      display: flex;
      width: 280px;
      height: calc(100% - 56px);
      background: white;
      flex-direction: column;
      border-left: 1px solid #d9d9db;

      .tag-tab {
        height: 66px;

        .no-search {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 20px 20px 20px 24px;

          .name {
            color: rgba(25, 25, 48, 0.75);
            .font14b();
          }

          .add-btn {
            display: inline-block;
            margin-left: 17px;
            width: 26px;
            height: 26px;
            font-size: 16px;
            text-align: center;
            color: rgba(25, 25, 48, 0.75);
            border-radius: 6px;
            line-height: 26px;
            cursor: pointer;

            &:hover {
              background: rgba(0, 0, 0, 0.05);
            }
          }

          .search-icon {
            display: inline-block;
            width: 26px;
            height: 26px;
            font-size: 16px;
            text-align: center;
            color: rgba(25, 25, 48, 0.75);
            cursor: pointer;
            line-height: 26px;
            border-radius: 6px;

            &:hover {
              background: rgba(0, 0, 0, 0.05);
            }
          }
        }

        .search {
          padding: 12px 24px;

          .close-search-btn {
            cursor: pointer;
            color: rgba(25, 25, 48, 0.75);
          }
        }
      }

      .tag-column {
        display: flex;
        align-items: center;
        padding: 11px 0 11px 16px;
        height: 40px;
        border-bottom: 1px solid #e8e8eb;

        .name {
          padding-left: 8px;
          width: 92px;
        }

        .attribute {
          display: flex;
          align-items: center;
          padding-left: 8px;
          width: calc(100% - 150px);
        }

        .number {
          cursor: pointer;
          display: flex;
          align-items: center;
          width: 50px;
          white-space: nowrap;

          .sort-btn {
            margin-right: 10px;

            .btn {
              width: 9px;
              font-size: 10px;
              color: rgba(25, 25, 48, 0.2);

              &:first-child {
                margin-top: 1px;
              }

              &:last-child {
                margin-top: -3px;
              }

              &--active {
                color: @primary1;
              }
            }
          }
        }
      }

      .tag-list {
        flex: 1;
        overflow-y: auto;
        padding: 8px 0;
        margin-top: 8px;

        .tag-li {
          position: relative;
          display: flex;
          align-items: center;
          padding-left: 16px;
          margin-bottom: 8px;
          height: 44px;
          cursor: default;

          &:hover {
            background: #f5f5f5;
          }

          &--active {
            background: #f5f5f5;
          }

          .tag-name {
            padding: 0 7px;
            width: 94px;
            box-sizing: border-box;

            span {
              display: inline-block;
              padding: 3px 6px;
              .elliptical-1();

              width: 78px;
              height: 30px;
              text-align: left;
              color: #1868e9;
              background: rgba(24, 104, 233, 0.08);
              border: 1px solid rgba(0, 0, 0, 0.05);
              border-radius: 6px;
              line-height: 22px;
            }
          }

          .content {
            padding: 0 24px 0 8px;
            width: calc(100% - 150px);
            .elliptical-1();
          }

          .number {
            width: 50px;
            text-align: center;
          }

          .hover-btn {
            position: absolute;
            right: 24px;

            .btn {
              display: inline-block;
              width: 26px;
              height: 26px;
              font-size: 14px;
              text-align: center;
              color: rgba(16, 16, 20, 0.95);
              border-radius: 6px;
              cursor: pointer;
              line-height: 26px;

              &:hover {
                background: rgba(0, 0, 0, 0.05);
              }

              &:last-child {
                margin-left: 16px;
              }
            }
          }
        }
      }
    }
  }

  .file-content-img {
    display: flex;
    overflow: auto;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    border-radius: 2px;

    :deep(.ant-image-img) {
      display: block;
      margin: 0 auto;
      max-width: 100%;
      max-height: 480px;
      object-fit: contain;
    }

    .result-are {
      background: #dbdbdb;
      border-radius: 4px;

      #canvas {
        width: 726px;
        border-radius: 4px;
      }
    }

    .mark-result {
      margin-left: 24px;
      width: 220px;
      height: 100%;

      .result-title {
        padding: 0 0 14px;
        height: 44px;
        font-size: 14px;
        color: rgba(25, 25, 48, 0.75);
        font-weight: 700;
      }

      .result-list {
        overflow-y: auto;
        flex-shrink: 1;
        height: calc(100% - 44px - 54px);

        .result-li {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 4px 8px;
          margin-bottom: 12px;
          width: 90%;
          height: 30px;
          white-space: nowrap;
          color: rgba(16, 16, 20, 0.95);
          background: rgba(16, 16, 20, 0.08);
          border: 1px solid rgba(0, 0, 0, 0.05);
          border-radius: 6px;
          box-sizing: border-box;
          line-height: 22px;

          .result-li-left {
            display: flex;
            align-items: center;
            // width: 80%;
            width: 135px;

            .tag-text {
              display: inline-block;
              margin-left: 8px;
              width: 100%;
              .elliptical-1();
            }
          }

          .result-li-right {
            width: 10%;
            .elliptical-1();

            cursor: pointer;
          }

          svg path {
            fill: red;
          }

          .type-img {
            fill: red;
            filter: hue-rotate(90deg);

            svg path {
              fill: red;
            }
          }
        }
      }

      .goto-mark {
        padding: 4px 0;
        height: 54px;

        .btn {
          width: 100%;
        }
      }
    }
  }
</style>
